{{!

  Copyright (c) Facebook, Inc. and its affiliates.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

}}{{!

This template should always mirror types.pyx but for mypy typing

}}
{{> common/AutoGeneratedPy}}

import folly.iobuf as _fbthrift_iobuf
import thrift.py3.types
import thrift.py3.exceptions
from thrift.py3.types import __NotSet, NOTSET
import typing as _typing
from typing_extensions import Final

import sys
import itertools
{{#program:has_stream?}}
import thrift.py3.stream
{{/program:has_stream?}}
{{#program:includeNamespaces}}
{{#hasTypes?}}
import {{#includeNamespace}}{{value}}.{{/includeNamespace}}types as _{{#includeNamespace}}{{value}}_{{/includeNamespace}}types
{{/hasTypes?}}
{{/program:includeNamespaces}}


__property__ = property


{{#program:enums}}
class {{enum:name}}(thrift.py3.types.{{^enum:flags?}}Enum{{/enum:flags?}}{{#enum:flags?}}Flag{{/enum:flags?}}):
    {{#enum:values}}
    {{enum_value:py_name}}: {{enum:name}} = ...
    {{/enum:values}}
    {{^enum:values}}
    pass
    {{/enum:values}}


{{/program:enums}}
{{#program:structs}}
class {{struct:name}}({{> types/PythonStructClass}}, _typing.Hashable):
    class __fbthrift_IsSet:
    {{#struct:py3_fields}}
        {{#field:has_ref_accessor?}}
        {{field:py_name}}: bool
        {{/field:has_ref_accessor?}}
    {{/struct:py3_fields}}
        pass

    {{#struct:fields_and_mixin_fields}}
    {{field:py_name}}: Final[{{#field:PEP484Optional?}}_typing.Optional[{{/field:PEP484Optional?}}{{!
            }}{{#field:type}}{{> types/PEP484Type}}{{/field:type}}{{!
            }}{{#field:PEP484Optional?}}]{{/field:PEP484Optional?}}] = ...

    {{/struct:fields_and_mixin_fields}}
    def __init__(
        self, {{#struct:py3_fields?}}*{{/struct:py3_fields?}}{{#struct:py3_fields}},
        {{field:py_name}}: _typing.Optional[{{#field:type}}{{> types/PEP484Type}}{{/field:type}}]=None{{/struct:py3_fields}}
    ) -> None: ...

    {{#struct:plain?}}
    def __call__(
        self, {{#struct:py3_fields?}}*{{/struct:py3_fields?}}{{#struct:py3_fields}},
        {{field:py_name}}: _typing.Union[{{#field:type}}{{> types/PEP484Type}}{{/field:type}}, __NotSet, None]=NOTSET{{/struct:py3_fields}}
    ) -> {{struct:name}}: ...

    def __reduce__(self) -> _typing.Tuple[_typing.Callable, _typing.Tuple[_typing.Type['{{struct:name}}'], bytes]]: ...
    {{/struct:plain?}}
    def __hash__(self) -> int: ...
    def __str__(self) -> str: ...
    def __repr__(self) -> str: ...
    {{#struct:is_struct_orderable?}}
    def __lt__(self, other: '{{struct:name}}') -> bool: ...
    def __gt__(self, other: '{{struct:name}}') -> bool: ...
    def __le__(self, other: '{{struct:name}}') -> bool: ...
    def __ge__(self, other: '{{struct:name}}') -> bool: ...
    {{/struct:is_struct_orderable?}}
    {{#struct:union?}}

    class Type(thrift.py3.types.Enum):
        EMPTY: {{struct:name}}.Type = ...
    {{#struct:py3_fields}}
        {{field:py_name}}: {{struct:name}}.Type = ...
    {{/struct:py3_fields}}

    @staticmethod
    def fromValue(value: _typing.Union[None, {{#struct:py3_fields}}{{^first?}}, {{/first?}}{{#field:type}}{{> types/PEP484Type}}{{/field:type}}{{/struct:py3_fields}}]) -> {{struct:name}}: ...
    @__property__
    def value(self) -> _typing.Union[None, {{#struct:py3_fields}}{{^first?}}, {{/first?}}{{#field:type}}{{> types/PEP484Type}}{{/field:type}}{{/struct:py3_fields}}]: ...
    @__property__
    def type(self) -> "{{struct:name}}.Type": ...
    {{/struct:union?}}


{{/program:structs}}
{{#program:containerTypes}}
{{#type:list?}}
_{{> types/CythonPythonType}}T = _typing.TypeVar('_{{> types/CythonPythonType}}T', bound={{> types/PEP484Containers}})


{{/type:list?}}
class {{> types/CythonPythonType}}({{> types/PEP484Containers}}, _typing.Hashable):
    def __init__(self, items: _typing.Optional[{{> types/PEP484Containers}}]=None) -> None: ...
    def __len__(self) -> int: ...
    def __hash__(self) -> int: ...
    def __copy__(self) -> {{> types/PEP484Containers}}: ...
{{#type:list?}}
    @_typing.overload
    def __getitem__(self, i: int) -> {{#type:list_elem_type}}{{> types/PEP484Type}}{{/type:list_elem_type}}: ...
    @_typing.overload
    def __getitem__(self, s: slice) -> {{> types/PEP484Containers}}: ...
    def __add__(self, other: {{> types/PEP484Containers}}) -> '{{> types/CythonPythonType}}': ...
    def __radd__(self, other: _{{> types/CythonPythonType}}T) -> _{{> types/CythonPythonType}}T: ...
    def __reversed__(self) -> _typing.Iterator[{{#type:list_elem_type}}{{> types/PEP484Type}}{{/type:list_elem_type}}]: ...
    def __iter__(self) -> _typing.Iterator[{{#type:list_elem_type}}{{> types/PEP484Type}}{{/type:list_elem_type}}]: ...
{{/type:list?}}
{{#type:set?}}
    def __contains__(self, x: object) -> bool: ...
    def union(self, other: {{> types/PEP484Containers}}) -> '{{> types/CythonPythonType}}': ...
    def intersection(self, other: {{> types/PEP484Containers}}) -> '{{> types/CythonPythonType}}': ...
    def difference(self, other: {{> types/PEP484Containers}}) -> '{{> types/CythonPythonType}}': ...
    def symmetric_difference(self, other: {{> types/PEP484Containers}}) -> '{{> types/CythonPythonType}}': ...
    def issubset(self, other: {{> types/PEP484Containers}}) -> bool: ...
    def issuperset(self, other: {{> types/PEP484Containers}}) -> bool: ...
    def __iter__(self) -> _typing.Iterator[{{#type:set_elem_type}}{{> types/PEP484Type}}{{/type:set_elem_type}}]: ...
{{/type:set?}}
{{#type:map?}}
    def __getitem__(self, key: {{#type:key_type}}{{> types/PEP484Type}}{{/type:key_type}}) -> {{#type:value_type}}{{> types/PEP484Type}}{{/type:value_type}}: ...
    def __iter__(self) -> _typing.Iterator[{{#type:key_type}}{{> types/PEP484Type}}{{/type:key_type}}]: ...
{{/type:map?}}


{{/program:containerTypes}}
{{#program:constants}}
{{#constant:type}}
{{constant:name}}: {{> types/PythonType}} = ...
{{/constant:type}}
{{/program:constants}}
{{#program:typedefs}}
{{typedef:name}} = {{#typedef:type}}{{> types/PythonType}}{{/typedef:type}}
{{/program:typedefs}}
{{#program:has_stream?}}

{{#program:stream_types}}
class ClientBufferedStream__{{type:flat_name}}(thrift.py3.stream.ClientBufferedStream[{{ > types/PEP484Type}}]):
    def __aiter__(self) -> _typing.AsyncIterator[{{ > types/PEP484Type}}]: ...
    async def __anext__(self) -> {{ > types/PEP484Type}}: ...

class ServerStream__{{type:flat_name}}(thrift.py3.stream.ServerStream[{{ > types/PEP484Type}}]):
    pass

class ServerPublisher_{{> types/CythonCppTypeIdent}}(thrift.py3.stream.ServerPublisher):
    def complete(self) -> None: ...
    def send(self, item: {{> types/CythonPythonType}}) -> None: ...

{{/program:stream_types}}
{{#program:response_and_stream_types}}{{!
}}class ResponseAndClientBufferedStream__{{> stream/ResponseClassNameSuffix}}(thrift.py3.stream.ResponseAndClientBufferedStream[{{#type:stream_first_response_type}}{{> types/PEP484Type}}{{/type:stream_first_response_type}}, {{#type:stream_elem_type}}{{> types/PEP484Type}}{{/type:stream_elem_type}}]):
    def __iter__(self) -> _typing.Tuple[
        {{#type:stream_first_response_type}}{{> types/PEP484Type}}{{/type:stream_first_response_type}},
        {{#type:stream_elem_type}}ClientBufferedStream__{{type:flat_name}}{{/type:stream_elem_type}},
    ]: ...

class ResponseAndServerStream__{{> stream/ResponseClassNameSuffix}}(thrift.py3.stream.ResponseAndServerStream[{{#type:stream_first_response_type}}{{> types/PEP484Type}}{{/type:stream_first_response_type}}, {{#type:stream_elem_type}}{{> types/PEP484Type}}{{/type:stream_elem_type}}]):
    pass

{{/program:response_and_stream_types}}
{{/program:has_stream?}}
